{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成器基本使用方法\n",
    "from collections import Iterable\n",
    "from collections.abc import Iterator\n",
    "\n",
    "def generator_test():\n",
    "    i = 1\n",
    "    while i < 10:\n",
    "        yield '<%d>' % i                        # yield 返回, 下次调用 __next__() 从此处继续\n",
    "        i += 1\n",
    "\n",
    "print(generator_test())                         # 返回值是generator\n",
    "print(generator_test)                           # 返回值是函数本身\n",
    "print(isinstance(generator_test(), Iterator))   # 迭代器\n",
    "print(isinstance(generator_test(), Iterable))   # 具有迭代能力\n",
    "\n",
    "it = generator_test()\n",
    "while True: \n",
    "    try:\n",
    "        print(it.__next__(), end=' ')           # 用 __next__() 迭代\n",
    "    except StopIteration:\n",
    "        print('stop!')\n",
    "        break\n",
    "    \n",
    "for item in generator_test():                   # 用for循环迭代\n",
    "    print(item, end=' ')\n",
    "print('stop!')\n",
    "\n",
    "gen = (x for x in generator_test())             # 生成器表达式\n",
    "for item in gen:\n",
    "    print(item, end=' ')\n",
    "print('stop!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用生成器实现斐波那切数列\n",
    "def fib(n):\n",
    "    a, b = 0, 1             # 定义第一,二项\n",
    "    while b <= n:           \n",
    "        yield b             # 返回第二项\n",
    "        a, b = b, a + b     # 计算\n",
    "\n",
    "for item in fib(100):\n",
    "    print(item, end=' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成器send函数1\n",
    "def generate_test():\n",
    "    print('第一次进入函数')\n",
    "    while True:\n",
    "        n = yield '中途赋值语句返回'\n",
    "        try:\n",
    "            if n % 2 == 1:\n",
    "                yield '奇数'\n",
    "            else:\n",
    "                yield '偶数'\n",
    "        except TypeError as e:\n",
    "            print('发生了异常:(%s)' % e)\n",
    "\n",
    "gen = generate_test()\n",
    "print(gen.__next__())   # 第一次运行 __next__() 停在第一个 yield\n",
    "print(gen.__next__())   # 第二次运行 __next__() 抛出异常，循环到第一个 yield返回"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成器send函数2\n",
    "gen = generate_test()\n",
    "try:\n",
    "    gen.send(100)            # 不能在generator刚运行时就传入非None的值\n",
    "except TypeError as e:\n",
    "    print('发生了异常:(%s)' % e)\n",
    "    \n",
    "gen = generate_test()       # 刚运行时传入一个None却是可以的\n",
    "gen.send(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成器send函数3\n",
    "gen = generate_test()\n",
    "print(gen.__next__())   # 中途返回\n",
    "print(gen.send(9))      # n = 9\n",
    "print(gen.__next__())   # 中途返回\n",
    "print(gen.send(10))     # n = 10"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "69bd962f501c29508fe434b835928c9b89fb5a50a44ab722852ffcc7148156fc"
  },
  "kernelspec": {
   "display_name": "Python 3.6.3 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "orig_nbformat": 2
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
